package com.only4play.common;

import com.only4play.common.constants.ErrorCodeEnum;
import com.only4play.common.exception.ApplicationException;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;

/**
 * @author liyuncong
 * @version 1.0
 * @file PasswordGenerator
 * @brief 密码生成器
 * @details 密码生成器
 * @date 2023-11-18
 *
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                     NAME               DESCRIPTION
 * 2023-11-18               liyuncong          Created
 */
public interface PasswordGenerator {
    String DELIMITER = ":";
    String DEFAULT_ALGORITHM = "MD5";

    /**
     * 密码加密
     *
     * @param loginUsername   登录名
     * @param loginPassword   密码
     * @param salt            加密盐
     * @param passwordEncoder 加密器
     * @return 加密结果
     */
    default String generate(String loginUsername, String loginPassword, String salt, PasswordEncoder passwordEncoder) {
        String rawPassword = construct(loginUsername, loginPassword, salt);
        return passwordEncoder.encode(rawPassword);

    }

    /**
     * 密码验证
     *
     * @param loginUsername   登录名
     * @param loginPassword   密码
     * @param salt            加密盐
     * @param encodePassword  加密后的密码
     * @param passwordEncoder 加密器
     * @return 验证结果
     */
    default boolean verify(String loginUsername, String loginPassword, String salt, String encodePassword, PasswordEncoder passwordEncoder) {
        String rawPassword = construct(loginUsername, loginPassword, salt);
        return passwordEncoder.matches(rawPassword, encodePassword);
    }

    /**
     * 密码加密串组装
     *
     * @param loginUsername 登录名
     * @param loginPassword 密码
     * @param salt          加密盐
     * @return 生成结果
     */
    default String construct(String loginUsername, String loginPassword, String salt) {
        try {
            MessageDigest digest = MessageDigest.getInstance(DEFAULT_ALGORITHM);
            String content = loginUsername + DELIMITER + salt + DELIMITER + loginPassword;
            byte[] bytes = digest.digest(content.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception exception) {
            throw new ApplicationException(ErrorCodeEnum.SERVER_ERROR);
        }
    }

}
